package SwingView.Lecture;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File;
import java.util.Date;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import org.jdesktop.swingx.JXDatePicker;
import org.jdesktop.swingx.JXMonthView;

import SwingController.CmsPresenter;
import SwingModel.CmsLecture;
import SwingView.CmsTimeSelector;


public class LectureUploadPanel extends JPanel{
	private static final int PANEL_WIDTH = 600;
	private static final int PANEL_HEIGHT = 190;
	
	private JLabel jlUlTitle;
	private JLabel jlNotification;
	private JLabel jlFNameTitle;
	private JLabel jlFName;
	private JButton jbBrowse;
	private JLabel jlAvaiDate;
	private JLabel jlExpDate;
	private JCheckBox avaiDateCheckBox;
	private JCheckBox expDateCheckBox;
	private JXDatePicker avaiDatePicker;
	private JXDatePicker expDatePicker;
	private CmsTimeSelector avaiTimeSelector;
	private CmsTimeSelector expTimeSelector;
	private JButton clearButton;
	private JButton postButton;
	
	private JFileChooser fc;
	
	//Fields
	private File selectedFile;
	
	//---------------------------------------------------------
	//CONSTRUCTOR:
	//---------------------------------------------------------		
	public LectureUploadPanel(){
		
		//instantiate file chooser
		fc = new JFileChooser();
		fc.setCurrentDirectory(new File(System.getProperty("user.home") + File.separator + "Documents"));
		
		//instantiate the fields:
		selectedFile = null;
		
		//set up the Panel
		setPreferredSize(new Dimension(PANEL_WIDTH,PANEL_HEIGHT));
		setMinimumSize(new Dimension(PANEL_WIDTH,PANEL_HEIGHT));
		setMaximumSize(new Dimension(PANEL_WIDTH,PANEL_HEIGHT));
		setOpaque(false);
		setForeground(new Color(210,210,210));
		setBorder(BorderFactory.createEmptyBorder(8,10,8,8));
		setLayout(new GridBagLayout());
		GridBagConstraints c;
		
		//Add upload Title
		JPanel jpT = new JPanel();
		jpT.setOpaque(false);
		jpT.setLayout(new BorderLayout());
		jlUlTitle = new JLabel ("<HTML><U>Upload new lecture file:<U><HTML>");
		jlUlTitle.setFont(jlUlTitle.getFont().deriveFont(17.0f).deriveFont(Font.BOLD));
		jpT.add(jlUlTitle,BorderLayout.WEST);
		
		
		//Add notification Title
		jlNotification = new JLabel();
		jlNotification.setFont(jlNotification.getFont().deriveFont(Font.BOLD).deriveFont(11.0f));
		jlNotification.setForeground(Color.RED);
		jpT.add(jlNotification,BorderLayout.CENTER);
		c = new GridBagConstraints();
		c.anchor = GridBagConstraints.FIRST_LINE_START;
		c.ipadx = 5;
		c.ipady = 5;
		c.weightx = 1.0;
		c.gridwidth = 3;
		c.fill = GridBagConstraints.HORIZONTAL;
		add(jpT,c);
		
		
		//Add File name Title
		jlFNameTitle = new JLabel("File Name:");
		jlFNameTitle.setFont(jlFNameTitle.getFont().deriveFont(14.0f));
		c = new GridBagConstraints();
		c.anchor = GridBagConstraints.LINE_START;
		c.gridy = 1;
		add(jlFNameTitle,c);
		
		//Add File Label:
		jlFName = new JLabel("<<Please Browse for a file>>");
		jlFName.setFont(jlFName.getFont().deriveFont(12.0f).deriveFont(Font.BOLD));
		jlFName.setForeground(new Color(55,55,55));
		jlFName.setBorder(BorderFactory.createEmptyBorder(0, 7, 0, 0));
		c = new GridBagConstraints();
		c.gridx = 1;
		c.gridy = 1;
		c.weightx = 1.0;
		c.fill = GridBagConstraints.HORIZONTAL;
		c.weighty = 1.0;
		c.anchor = GridBagConstraints.CENTER;
		add(jlFName,c);
		
		//Add Browse button
		jbBrowse = new JButton("Select File");
		jbBrowse.setForeground(Color.BLUE);
		jbBrowse.setOpaque(false);
		jbBrowse.setBorder(BorderFactory.createEmptyBorder(0,8,0,3));
		jbBrowse.setCursor(new Cursor(Cursor.HAND_CURSOR));
		jbBrowse.addActionListener(new BrowseActionListener());
		c = new GridBagConstraints();
		c.gridx = 2;
		c.gridy = 1;
		c.anchor = GridBagConstraints.LINE_END;
		add(jbBrowse,c);
		
		//Add Available Date Title:
		jlAvaiDate = new JLabel("Available Date: ");
		jlAvaiDate.setFont(jlFNameTitle.getFont().deriveFont(14.0f));
		c = new GridBagConstraints();
		c.gridy = 2;
		c.anchor = GridBagConstraints.LINE_START;
		add(jlAvaiDate,c);
		
		//Add Available Date Picker:
		avaiDatePicker = new JXDatePicker();
		avaiDatePicker.setName("Select Available Date");
		avaiDatePicker.setDate(new Date());
		
		//Add Avai Date Time Selector
		avaiTimeSelector = new CmsTimeSelector();
		
		//Add Available Date CheckBox:
		avaiDateCheckBox = new JCheckBox();
		avaiDateCheckBox.setSelected(true);
		
		//AvaiDate helper panel:
		JPanel jpAvaiDate = new JPanel();
		jpAvaiDate.setOpaque(false);
		jpAvaiDate.setLayout(new FlowLayout(FlowLayout.LEFT,5,0));
		jpAvaiDate.add(avaiDateCheckBox);
		jpAvaiDate.add(avaiDatePicker);
		jpAvaiDate.add(avaiTimeSelector);
		c = new GridBagConstraints();
		c.gridx = 0;
		c.gridy = 3;
		c.gridwidth = 3;
		c.anchor = GridBagConstraints.LINE_START;
		add(jpAvaiDate,c);
		
		//Add Exp Date Title:
		jlExpDate = new JLabel("Expiration Date: ");
		jlExpDate.setFont(jlExpDate.getFont().deriveFont(14.0f));
		c = new GridBagConstraints();
		c.gridy = 4;
		c.anchor = GridBagConstraints.LINE_START;
		add(jlExpDate,c);
		
		//Add Exp Date Date selector
		expDatePicker = new JXDatePicker();
		expDatePicker.setName("Select Expiration Date");
		expDatePicker.setDate(new Date(CmsPresenter.END_OF_SEMESTER.getTime()));//set date to the date of tomorrow (+1 day)
		
		//Add Exp Date Time selector
		expTimeSelector = new CmsTimeSelector();
		
		//Add Exp Date Check Box:
		expDateCheckBox = new JCheckBox();
		expDatePicker.setEnabled(false);//default to be disable
		expTimeSelector.setEnabled(false);//default to be disable
		expDateCheckBox.setSelected(false);//default to be "unchecked"
		
		//Expiration Date Helper Panel:
		JPanel jpExpDate = new JPanel();
		jpExpDate.setOpaque(false);
		jpExpDate.setLayout(new FlowLayout(FlowLayout.LEFT,5,0));
		jpExpDate.add(expDateCheckBox);
		jpExpDate.add(expDatePicker);
		jpExpDate.add(expTimeSelector);
		c = new GridBagConstraints();
		c.gridx = 0;
		c.gridy = 5;
		c.weightx = 1.0;
		c.gridwidth = 3;
		c.anchor = GridBagConstraints.LINE_START;
		add(jpExpDate,c);
		
		//add clear Button
		JPanel jp = new JPanel(); //helper panel for the buttons
		jp.setOpaque(false);
		jp.setLayout(new GridLayout(1,2, 10, 0));
		clearButton = new JButton("Clear");
		clearButton.setFont(clearButton.getFont().deriveFont(Font.BOLD).deriveFont(13.0f));
		clearButton.setPreferredSize(new Dimension(75,20));
		clearButton.setMinimumSize(new Dimension(75,20));
		clearButton.setBackground(new Color(170,170,170));
		clearButton.setForeground(new Color(30,30,30));
		clearButton.setOpaque(true);
		clearButton.setBorder(BorderFactory.createLineBorder(new Color(30,30,30)));
		jp.add(clearButton);
		
		//add post button
		postButton = new JButton("Post");
		postButton.setFont(postButton.getFont().deriveFont(Font.BOLD).deriveFont(13.0f));
		postButton.setPreferredSize(new Dimension(75,20));
		postButton.setMinimumSize(new Dimension(75,20));
		postButton.setBackground(new Color(170,170,170));
		postButton.setForeground(new Color(30,30,30));
		postButton.setOpaque(true);
		postButton.setBorder(BorderFactory.createLineBorder(new Color(30,30,30)));
		
		jp.add(postButton);
		c = new GridBagConstraints();
		c.gridy = 6;
		c.gridwidth = 3;
		c.anchor = GridBagConstraints.PAGE_END;
		c.weightx = 1.0;
		c.weighty = 0.4;
		add(jp,c);
		
		
		//-------------------------------------------------------------------
		//ACTION LISTENERS:
		//avai TimeSelector
		clearButton.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				clearAllInput();
			}
			
		});
		
		
		//-------------------------------------------------------------------
		//ACTION LISTENERS:
		//avai TimeSelector
		avaiTimeSelector.addItemListener(new ItemListener(){
			@Override
			public void itemStateChanged(ItemEvent e) {
				validateDateInput();
			}
		});
		
		//-------------------------------------------------------------------
		//ACTION LISTENERS:
		//exp TimeSelector
		expTimeSelector.addItemListener(new ItemListener(){
			@Override
			public void itemStateChanged(ItemEvent e) {
				validateDateInput();
			}
		});
		
		//-------------------------------------------------------------------
		//ACTION LISTENERS:
		//avai DatePicker		
		avaiDatePicker.addActionListener(new ActionListener(){
			@Override
			public void actionPerformed(ActionEvent e) {
				validateDateInput();
			}
		});
		
		//-------------------------------------------------------------------
		//ACTION LISTENERS:
		//exp DatePicker		
		expDatePicker.addActionListener(new ActionListener(){
			@Override
			public void actionPerformed(ActionEvent e) {
				validateDateInput();
			}
		});
		
		//-------------------------------------------------------------------
		//ACTION LISTENERS:
		//Avai Date CheckBox
		avaiDateCheckBox.addItemListener(new ItemListener(){

			@Override
			//Perform when check box is checked and unchecked
			public void itemStateChanged(ItemEvent e) {
				JCheckBox cb = (JCheckBox) e.getSource();
				if(!cb.isSelected()){ //checkbox is unchecked - unable date and time selector
					avaiDatePicker.setEnabled(false);
					avaiTimeSelector.setEnabled(false);
				}
				else { // check box is checked - enable date and time selector
					avaiDatePicker.setEnabled(true);
					avaiTimeSelector.setEnabled(true);
				}
			}
		});
		
		//-------------------------------------------------------------------
		//ACTION LISTENERS:
		//Exp Date CheckBox
		expDateCheckBox.addItemListener(new ItemListener(){

			@Override
			//Perform when check box is checked and unchecked
			public void itemStateChanged(ItemEvent e) {
				JCheckBox cb = (JCheckBox) e.getSource();
				if(!cb.isSelected()){ //checkbox is unchecked - unable date and time selector
					expDatePicker.setEnabled(false);
					expTimeSelector.setEnabled(false);
				}
				else { // check box is checked - enable date and time selector
					expDatePicker.setEnabled(true);
					expTimeSelector.setEnabled(true);
				}
			}
		});
	}
	

	//---------------------------------------------------------
	//METHOD: setNotificationMessage
	//---------------------------------------------------------
	/**
	 * display a notification on the upload new lecture file
	 * panel
	 * @param notification
	 */
	public void setNotificationMessage(String notification){
		jlNotification.setText("  " + notification);
	}
	
	
	public File getSelectedFile(){
		return selectedFile;
	}
	
	public Date getSelectedAvaiDate(){
		Date avaiDate;
		
		if(avaiDateCheckBox.isSelected()){
			long dayMilis = avaiDatePicker.getDate().getTime();
			long timeMilis = avaiTimeSelector.getHour() * 60 * 60 * 1000 //milisecond = hour * 60min * 60sec * 1000milis
					+ avaiTimeSelector.getMinute() * 60 * 1000;//milisecond = min * 60sec * 1000milis
			avaiDate = new Date(dayMilis + timeMilis);
		}
		else avaiDate = new Date();
		
		return avaiDate;
	}
	
	public Date getSelectedExpDate(){
		Date expDate;
		
		if(this.expDateCheckBox.isSelected()){
			long dayMilis = expDatePicker.getDate().getTime();
			long timeMilis = expTimeSelector.getHour() * 60 * 60 * 1000 //milisecond = hour * 60min * 60sec * 1000milis
					+ expTimeSelector.getMinute() * 60 * 1000;//milisecond = min * 60sec * 1000milis
			expDate = new Date(dayMilis + timeMilis);
		}
		else expDate = new Date(CmsPresenter.DEFAULT_EXP_DATE.getTime());
		
		return expDate;
	}
	
	
	public void addALLecturePost(ALLecturePost allp){
		this.postButton.addActionListener(allp);
	}
	
	//---------------------------------------------------------
	//CLASS: BrowseActionListener
	//---------------------------------------------------------
	/**
	 * This ActionListener class open a file browser for user to
	 * select a file and then set the Selected File.
	 * @author KimDo
	 *
	 */
	private class BrowseActionListener implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent e) {
			int returnVal = fc.showOpenDialog(null);
			
			if( returnVal == JFileChooser.APPROVE_OPTION){
				System.out.println("Selected File: " + fc.getSelectedFile().getPath());
				selectedFile = new File(fc.getSelectedFile().getPath());
				jlFName.setText(fc.getSelectedFile().getName());
			}
			
		}
		
	}
	
	public void clearAllInput(){
		//clear file
		selectedFile = null;
		this.jlFName.setText("<<Please Browse for a file>>");
		
		//reset avaiDate
		avaiDatePicker.setDate(new Date());
		avaiDatePicker.setEnabled(true);
		avaiTimeSelector.setTime(0, 0);
		avaiTimeSelector.setEnabled(true);
		avaiDateCheckBox.setSelected(true);
		
		//reset expDate
		expDatePicker.setDate(new Date(CmsPresenter.END_OF_SEMESTER.getTime()));
		expTimeSelector.setTime(0, 0);
		expDatePicker.setEnabled(false);
		expTimeSelector.setEnabled(false);
		expDateCheckBox.setSelected(false);
		
		System.out.println("Lecture is CLEARED!");
	}
	
	//---------------------------------------------------------
	//METHOD: Validate all user input
	//---------------------------------------------------------	
	/**
	 * This method validate all user input including:
	 *  - File check
	 *  - Date check
	 */
	public boolean validateAllInput(){
		return validateFileInput() & validateDateInput();
	}
	
	
	
	//---------------------------------------------------------
	//METHOD: Validate user file input
	//---------------------------------------------------------	
	/**
	 * This method check if user has input any file
	 */
	public boolean validateFileInput(){
		if(getSelectedFile() == null){
			JOptionPane.showMessageDialog(CmsPresenter.mainView,
				    "Please select a file to upload!",
				    "ERROR!",
				    JOptionPane.ERROR_MESSAGE);
			System.out.println("false input");
			return false;
		}
		else{
			setNotificationMessage("");
			return true;
		}
	}
	
	//---------------------------------------------------------
	//METHOD: Validate user date input
	//---------------------------------------------------------	
	/**
	 * This method check if there is any conflict between avaiDate
	 * and expDate. avaiDate must be before expDate.
	 */
	public boolean validateDateInput(){
		//CHECK DATE:
		final Date avaiDate;
		final Date expDate;
		avaiDate = LectureUploadPanel.this.getSelectedAvaiDate();
		expDate = LectureUploadPanel.this.getSelectedExpDate();
		
		if(avaiDate.compareTo(expDate) >= 0){
			JOptionPane.showMessageDialog(CmsPresenter.mainView,
				    "The available Date and Time have to be before the expiration Date and Time!",
				    "ERROR!",
				    JOptionPane.ERROR_MESSAGE);
			return false;
		}
		else{
			return true;
		}
	}
	
	//Paint rounded rectangle on the back ground
	@Override
	protected void paintComponent(Graphics g){
		super.paintComponent(g);
		g.fillRoundRect(0, 0, this.getWidth(), this.getHeight(), 7, 7);
	}


}
